<template>
	<div class="zd-billlist">
		<div class="main-head">
			<p class="condition">
				<label>状态：</label>
				<span @click="changeState(item)" v-for="(item,index) in billStateNum" :key="index" :class="{active:item.isActive}">
					{{item.name}}&nbsp;{{item.billNum}}
				</span> 			
			</p>
			<div class="select">
				<div class="firstColumn">
					<div>
						<span>项目：</span>
						<el-select style="min-width:210px" v-model="selectedProject" placeholder="请选择活动区域">
							<el-option v-for="item in storeId" :key="item.id" :label="item.label" :value="item.value"></el-option>
						</el-select>
					</div>
					<div>
						<span>月份：</span>
						<el-date-picker style="max-width:150px" v-model="monthStart"  format="yyyy 年 MM 月" value-format="yyyyMM" type="month" placeholder="选择起始月">
						</el-date-picker>
						&nbsp;至&nbsp;
						<el-date-picker style="max-width:150px" v-model="monthEnd"  format="yyyy 年 MM 月" value-format="yyyyMM" type="month" placeholder="选择结束月">
						</el-date-picker>
					</div>
				</div>
				<div class="secondColumn">
					<div>
						<span>对账单号：</span>
						<el-input class="billNum" style="width: 140px;" v-model="billNum" placeholder="请输入对账单号"></el-input>
					</div>
					<div>
						<span>高级：</span>
						<el-input class="high-level" style="width: 220px;" v-model="keyword" placeholder="请输入合同号，商户名称或店招"></el-input>
					</div>
					<div>
						<el-button type="primary" @click="selectFetchData" :disabled="isDisabled">查询</el-button>
					</div>
				</div>
			</div>
		</div>
		<div class="main-content" v-loading="loading">
			<el-table class="table"  :default-sort="{prop: 'month', order: 'ascending'}" :data="tableData" style="width: 100%;" @cell-click="handleCellClick">
				<el-table-column label="对账单号" align="center">
					<template slot-scope="scope">
						<a href="#">{{ scope.row.billNum }}</a>
					</template>
				</el-table-column>
				<el-table-column prop="contractCode" label="合同编号" align="center">
				</el-table-column>
				<el-table-column prop="contractType" label="合同类型" align="center">
				</el-table-column>
				<el-table-column prop="tenantCode" label="商户代码" align="center">
				</el-table-column>				
				<el-table-column prop="tenantName" label="商户" align="center">
				</el-table-column>
				<el-table-column prop="month" label="月份" align="center">
				</el-table-column>
				<el-table-column prop="payTotal" label="应缴" align="center">
				</el-table-column>
				<el-table-column prop="payedTotal" label="已缴" align="center">
				</el-table-column>
				<el-table-column prop="unpayedTotal" label="未缴" align="center">
				</el-table-column>
				<el-table-column prop="billState" label="状态" align="center">
				</el-table-column>
			</el-table>
			<el-pagination class="el-pagination" @current-change="current_change" :page-size="pageSize" background layout="prev, pager, next" :total="total"  :current-page="currentPage">
			</el-pagination>
		</div>
	</div>
</template>

<script>
	export default {
		name: 'zd-billlist',
		data() {
			return {				
				loading: false, // 表格Loading加载
				isDisabled: false, // 查询按钮默认为可点击状态
				// 总条目数
				total:0,
				// 每页显示条目个数
				pageSize:5,
				// 默认页面
				currentPage: 1,

				monthStart:'', // 日历初始日期,需是字符串
				monthEnd:'', // 日历结束日期,需是字符串
				selectedProject: '', // 选中的项目
				billNum: '', // 对账单号
				keyword: '', // 高级(合同号或对账单号)

				tableData: [], // 需要展示的表格数据
				tableDataAll: [], // 表格数据全放在该数组
				fetchTimeArr:[], // 获得所有请求的月份(每月分次请求)
				fetchResponseData:[], // 所有请求的返回的数据,有单次请求，也有多次请求
				
				// 账单状态
				billStateNum: [
					{
						name:'全部',
						billNum: 0, //所有账单
						isActive:true
					},
					{
						name:'已发布',
						billNum:0, //已发布账单
						isActive:false
					},
					{
						name:'已确认',
						billNum: 0, //已确认账单
						isActive:false
					},
					{
						name:'部分结款',
						billNum: 0, //部分结款账单
						isActive:false
					},
					{
						name:'已结款',
						billNum: 0, //已结款账单
						isActive:false
					}				
				],

				fetchParams: {}, // 记录请求参数
				changedStateItem: '全部' // 状态切换，当前的状态，默认状态为全部
			}
		},
		computed:{
			loginResData(){
				// 登录信息
				try{
					if(localStorage.getItem('loginResData')){
						return JSON.parse(localStorage.getItem('loginResData'))
					} else {
						throw new Error('localStorage中的loginResData不存在，请退出重新登录')
					}
				}catch(err){
					this.$message.error(`${err}`)
				}					
			},
			storeId(){
				// 项目ID
				// localStorage=>loginResData=>stores=>name
				let projectArr=[];
				this.loginResData.stores.forEach((val, index) => {
					projectArr.push({id:index, label:val.name, value:val.uuid})
				})
				return projectArr;			 
			},
			contracts(){
				// 合同uuid
				// localStorage=>loginResData=>stores=>contracts=>uuid
				let storeContractsCodeArr = [];
				this.loginResData.stores.forEach( val => {
					let contracts = val.contracts;
					contracts.forEach(val => {
						storeContractsCodeArr.push(val.uuid)
					})
				})
				return storeContractsCodeArr;				
			},
			tenantId(){
				// 商户uuid
				// localStorage=>loginResData=>tenant=>uuid
				return this.loginResData.tenant.uuid;	
			},
			userGroups(){
				// userGroups
				return this.loginResData.userGroups
			}
		},
		methods: {
			current_change(val){
				 // val为当前页
				 this.tableData = this.tableDataAll.slice((val-1)*this.pageSize,val*this.pageSize)
			},
			handleCellClick(row, column, cell) {
				// 由fetchResponseData从登录数据中获得stores的uuid
				const resData = this.fetchResponseData;
				resData.forEach( val => {
					const billLists = val.data.data;
					billLists.forEach( billVal =>{
						if(billVal.billNo == row.billNum ){
							// 存储当前对账单号对应的账单数据
							localStorage.setItem('currentBillNoOfBillList',JSON.stringify(billVal))
						}
					})
				})
				// 存储请求参数
					// 月份重设
					this.fetchParams.beginSettle = this.monthStart
					this.fetchParams.endSettle = this.monthEnd	
				localStorage.setItem('fetchParams',JSON.stringify(this.fetchParams))
				sessionStorage.setItem('changedStateItem', this.changedStateItem)
				// 跳转到账单详情页
				this.$router.push({
					path: '/Main/BillConfirm'
				})
			},
			changeState (item) {
				this.changedStateItem = item.name
				// 从本地存储中获得当前加载的数据
				const tableDataAll = JSON.parse(sessionStorage.getItem('tableDataAll'))
				// 清空翻页相关数据
				this.tableData = []
				this.tableDataAll = []		
				this.total = 0		
				// 账单表头状态改变进行处理
				// 改变激活状态
				this.billStateNum.forEach(val => {
					val.isActive = false
					if (val.name === item.name) {
						val.isActive = true
					} 
				})
				// 改变对应表格数据
				let fillAction = (name) => {
					if(name === '全部') {
						if(tableDataAll != null) {
							tableDataAll.forEach(val => {
								this.tableDataAll.push(val)
								this.total ++	
							})						
						}
					} else {
						if(tableDataAll != null) {
							tableDataAll.forEach(val => {
								if (val.billState === name) {
									this.tableDataAll.push(val)
									this.total ++	
								}
							})
						}
					}
					// 初始化表格显示
					this.tableData = this.tableDataAll.slice(0,this.pageSize)
				}
				switch (item.name) {
					case '全部':
						fillAction(item.name)
						break;
					case '已发布':
						fillAction(item.name)
						break;
					case '已确认':
						fillAction(item.name)
						break;
					case '部分结款':
						fillAction(item.name)
						break;
					case '已结款':
						fillAction(item.name)
						break;																													
				}
			},
			initFetchBill(){
				const self = this;
				// 加载过程
				self.loading = true; 
				/**
				 * 包含开始时间：beginSettle，结束时间：endSettle
				 * 合同编号：contracts, 商户：storeId=>value(uuid)
				 * 用户组userGrops
				 * 默认contracts,storeId均取数组第一位
				 */				
				const jsonData = {
					beginSettle:self.monthStart,
					endSettle:self.monthEnd,
					contracts:self.contracts[0],
					storeId: self.storeId[0].value,
					userGroups: self.userGroups,
					tenantId:self.tenantId
				}

				// 记录每次请求的参数，作为之后返回对账单页面的初始化请求参数
				this.fetchParams = jsonData
				
				this.$axios.fetchBillList(jsonData)
				.then( res => {
					// 返回数据不为空进行的处理逻辑
					if(res.data.data){
						// 将所有请求值放入fetchResponseData中，使其他函数可用
						self.fetchResponseData.push(res);
						// 将请求获得的数据与表格进行匹配				
						self.responseDataMatchTable();
					}
					self.loading = false;	
				})
				.catch(err =>{
					// 获得错误信息处理
					self.$message.error(`${err}`)
					self.loading = false;						
				})
			},	
			backInitFetchBill(fetchParams){
				// 从账单详情页返回的初次请求
				const self = this;
				const parsedFetchParams = JSON.parse(fetchParams);
				self.loading = true; 
				// 数据重设
				self.monthStart = String(parsedFetchParams.beginSettle)
				self.monthEnd = String(parsedFetchParams.endSettle)
				// 月份清零
				self.fetchTimeArr = [];
				// 执行分月函数，进而得到月份数组
				self.getEveryMonth();	
				let fetchAllResponse = new Promise((resolve, reject) => {
					let forNum = 1;
					self.fetchTimeArr.forEach((val,index) => {
						// 请求参数
						let jsonData = {
							beginSettle: val,
							endSettle: val,
							contracts: parsedFetchParams.contracts,
							storeId: parsedFetchParams.storeId,
							userGroups: parsedFetchParams.userGroups,
							tenantId:self.tenantId
							
						}
						// 以下参数若值不为空则添加到jsonData对象中
						// 对账单号						
						if(parsedFetchParams.billNo){
							jsonData.billNo = parsedFetchParams.billNo;
						}
						// 高级(合同号或对账单号)
						if(parsedFetchParams.keyword){
							jsonData.keyword = parsedFetchParams.keyword;
						}
						// 记录每次请求的参数，作为之后返回对账单页面的初始化请求参数
						this.fetchParams = jsonData					
						// 请求数据
						this.$axios.fetchBillList(jsonData)
						.then( res => {
							forNum++
							// 返回值不为空才push到数组中
							if(res.data.data){
								self.fetchResponseData.push(res);
							}
							if(forNum > self.fetchTimeArr.length){
								// 此处抛出请求参数
								resolve(jsonData)
							}
						}).catch(err => {
							reject(err)
						})
					})
				})
				// 异步请求均结束后的处理逻辑
				fetchAllResponse
				.then( res => {
					// 将请求获得的全部数据进行异步处理					
					self.responseDataMatchTable();
					// Loading加载关闭
					self.loading = false;	
				})
				.catch(err =>{
					// 获得错误信息处理
					self.$message.error(`${err}`)
					// 加载过程消失
					self.loading = false;						
				})										
			},		
			selectFetchData(){
				const self = this;
				// 月份清零
				self.fetchTimeArr = [];
				// 执行分月函数，进而得到月份数组
				self.getEveryMonth();
				if(self.fetchTimeArr.length > 0){
					// 查询不可再次点击
					self.isDisabled = true;
					// Loading加载开启
					self.loading = true;
					// 总条目数清零
					self.total = 0;
					// 需要展示的表格数据清零
					self.tableData = [];
					// 存放所有表格数据的数组清零
					self.tableDataAll = [];
					// 之前所有请求的数据清空
					self.fetchResponseData = []
					// 头部状态清零
					self.billStateNum.forEach(val => {
						val.billNum = 0
					})
				}
				// 由数组的中的所有选择日期，进行遍历,请求数据，待所有异步请求均结束，抛出
				let fetchAllResponse = new Promise((resolve, reject) => {
					let forNum = 1;
					self.fetchTimeArr.forEach((val) => {
						// 请求参数
						let jsonData = {
							// 请求时间
							beginSettle: val,
							// 结束时间
							endSettle: val,
							// 合同编号uuid
							contracts: self.contracts[0],
							// 项目uuid
							storeId: self.storeId[0].value,
							userGroups: self.userGroups,
							tenantId:self.tenantId
						}
						// 以下参数若值不为空则添加到jsonData对象中
						// 项目名,此处为选择重设
						if(self.selectedProject){
							jsonData.storeId = self.selectedProject;
						}
						// 对账单号						
						if(self.billNum){
							jsonData.billNo = self.billNum;
						}
						// 高级(合同号或对账单号)
						if(self.keyword){
							jsonData.keyword = self.keyword;
						}
						// 请求数据
						this.$axios.fetchBillList(jsonData)
						.then( res => {
							forNum++
							// 返回值不为空才push到数组中
							if(res.data.data){
								self.fetchResponseData.push(res);
							}
							if(forNum > self.fetchTimeArr.length){
								// 此处抛出请求参数
								resolve(jsonData)
							}
						}).catch(err => {
							reject(err)
						})
					})
				})
				// 异步请求均结束后的处理逻辑
				fetchAllResponse
				.then( res => {
					// 记录请求的参数，作为之后返回对账单页面的初始化请求参数
					self.fetchParams = res
					// 月份重设
					self.fetchParams.beginSettle = self.monthStart
					self.fetchParams.endSettle = self.monthEnd

					self.responseDataMatchTable();
					self.loading = false
					self.isDisabled = false;
				})
				.catch(err =>{
					self.$message.error(`${err}`)
					self.loading = false;	
					self.isDisabled = false;		
				})
			},						
			responseDataMatchTable(){
				// 将请求的数据与表格进行配对
				const self = this;
				let resData = self.fetchResponseData;
				resData.forEach(eachFetch => {
					// 每次请求的数据
					const jsonData = eachFetch.data.data;
					jsonData.forEach( dataArr => {
						let listData = {
							billNum: dataArr.billNo ? dataArr.billNo : '---', // 对账单号
							contractCode: dataArr.contract.code ? dataArr.contract.code : '---', // 合同编号
							contractType:  dataArr.contractType ? dataArr.contractType : '---', // 合同类型
							tenantCode: dataArr.tenant.code ? dataArr.tenant.code : '---', // 商户代码
							tenantName: dataArr.contract.name ? dataArr.contract.name : '---', // 商户
							month: dataArr.billSettle ? dataArr.billSettle : '---', //月份 类似2017年12月
							payTotal: dataArr.payTotal ||  dataArr.payTotal == 0 ? dataArr.payTotal : '---',					
							payedTotal: dataArr.payedTotal || dataArr.payedTotal == 0 ? dataArr.payedTotal : '---',
							unpayedTotal: dataArr.unpayedTotal || dataArr.unpayedTotal == 0 ? dataArr.unpayedTotal : '---',
							billState: dataArr.billState ? dataArr.billState : '---' 
						}						
						// 设置状态总数
						this.billStateNum[0].billNum++
						switch (listData.billState) {
							case 'unpaid':
								listData.billState = '已发布' 
								this.billStateNum[1].billNum++ // 已发布数量
								break;
							case 'confirmed':
								listData.billState = '已确认'
								this.billStateNum[2].billNum++ // 已确认数量
								break;		
							case 'partialclosed':
								listData.billState = '部分结款'
								this.billStateNum[3].billNum++ // 部分结款数量
								break;
							case 'closed':
								listData.billState = '已结款'
								this.billStateNum[4].billNum++ // 已结款数量
								break;								
						}
						// 账单状态									
						// 将匹配到的每条数据放入总数据中，之后进行本地分页
						self.tableDataAll.push(listData)				
						// 设置总条目数
						self.total ++						
					})
				})
				// 初始化表格显示
				self.tableData = self.tableDataAll.slice(0,self.pageSize)
				// 将匹配好的数据存储在本地，为之后状态切换做准备
				sessionStorage.setItem('tableDataAll',JSON.stringify(self.tableDataAll))
				// 激活二次筛选条件的状态
				this.billStateNum.forEach(val => {
					if (val.name == this.changedStateItem) {
						val.isActive = true
					} else {
						val.isActive = false
					}
				})
				// 根据状态进行二次筛选
				this.billStateNum.forEach(val => {
					if (val.name == this.changedStateItem) {
						this.changeState(val)
					}
				})
			},			
			getEveryMonth(){
				const self = this;
				/**
				 * 开始月份不能大于结束月份
				 * 截止月份不得晚于当前月份
				 * 月份为每月请求一次
				 */

				// 获得当前年月
				const nowDate = new Date();
				const currentYear = nowDate.getFullYear(); //获取当前年份
				let currentMonth = nowDate.getMonth()+1; //获取当前月份
				// 月份不足10补0
				currentMonth = this.fillZero(currentMonth);
				// 当前完整时间
				const currentTime = `${currentYear}${currentMonth}`;

				const monthStart = self.monthStart;
				const monthEnd = self.monthEnd;
				if(monthStart > monthEnd){
					self.$message.error('起始日期不能大于结束日期')
					return;
				}else if(monthEnd > currentTime){
					self.$message.error('无法查询当前月份之后的账单')
					return;					
				} else {
					// 获得开始年份
					let gettedYearStart = monthStart.slice(0,4);
					// 获得结束年份
					let gettedYearEnd = monthEnd.slice(0,4);
					// 获得第一年开始月份
					let gettedMonthStart = monthStart.slice(4)
					// 获得最后一年结束月份
					let gettedMonthEnd = monthEnd.slice(4)

					//若年份相同，则只循环月份
					if(gettedYearStart == gettedYearEnd){
						for(let i = Number(gettedMonthStart); i<= Number(gettedMonthEnd); i++){
							// 不足10补0
							i = self.fillZero(i)
							self.fetchTimeArr.push(`${gettedYearStart}${i}`);
						}
					}
					//年份不同，第一年份为从定义月开始循环，最后年份为从定义月结束，中间循环以12为一周期
					if(gettedYearEnd > gettedYearStart){
						// 第一年份循环
						for(let i = Number(gettedMonthStart); i<=12; i++){
							// 不足10补0
							i = self.fillZero(i)
							self.fetchTimeArr.push(`${gettedYearStart}${i}`);
						}
						// 中间年份循环,需起始年份比结束年份小2
						if(gettedYearEnd - gettedYearStart >=2){
							for(let i = ++gettedYearStart; i<gettedYearEnd; i++){
								for(let j =1; j<=12; j++){
									// 不足10补0
									j = self.fillZero(j)
									self.fetchTimeArr.push(`${i}${j}`)
								}
							}
						}
						// 最后一年年份循环,需起始年份比结束年份小1
						for(let i = 1; i<= Number(gettedMonthEnd); i++){
							// 不足10补0
							i = self.fillZero(i)
							self.fetchTimeArr.push(`${gettedYearEnd}${i}`)
						}
					}
				}
			},
			fillZero(num){
				// 月份不足10补0
				num = num < 10 ? `0${num}` : num;
				return num;
			}
		},
		mounted:function(){
			/**
			 * 初始化日历
			 * monthStart为起始年月
			 * monthEnd为终止年月
			 */

			// 获得当前年月
			const nowDate = new Date();
			const currentYear = nowDate.getFullYear(); //获取当前年份
			let currentMonth = nowDate.getMonth()+1; //获取当前月份
			// 月份不足10补0
			currentMonth = this.fillZero(currentMonth);
			// 当前完整时间
			const currentTime = `${currentYear}${currentMonth}`;
			// elementui初始化时需赋值为String,默认当月账单
			this.monthStart = currentTime;
			this.monthEnd = currentTime;
			
			/**
			 * 初始化项目
			 */
			this.selectedProject = this.storeId[0].value;

			// 先清除本地缓存的数据
			sessionStorage.removeItem('tableDataAll')

			/**
			 * 初始化请求
			 * 初始化分为第一次登陆成功初始化和账单详情返回初始化
			 */

			// 查看是否存在fetchParams
			const fetchParams = localStorage.getItem('fetchParams');
			if(fetchParams){
				// 清除fetchParams
				localStorage.removeItem('fetchParams')
				this.changedStateItem = sessionStorage.getItem('changedStateItem')
				// 清除changedStateItem
				sessionStorage.removeItem('changedStateItem')
				// 激活当前状态
				this.billStateNum.forEach(val => {
					if(val.name === this.changedStateItem) {
						val.isActive = true
					} else {
						val.isActive = false
					}
				})
				this.backInitFetchBill(fetchParams)
			} else {
				this.initFetchBill()
			}
		}
	}
</script>

<style scoped lang="scss">
.zd-billlist {
  width: 100%;
  background-color: #ffffff;
}

.main-head {
  width: 98%;
  margin: 0 auto;
  text-align: left;
  border-bottom: 1px solid #cccccc;
  .condition {
	  padding-top:10px;
	  margin-bottom:10px;
	  height:50px;
	  display: flex;
	  align-items: center;
	& > label{
		white-space: nowrap;
	}
    & > span {
      margin: 0px 10px;
	  height: 70%;
      width: 80px;
      color: #000000;
      text-decoration: none;
	  cursor: pointer;
	  display: flex;
	  padding:0 10px;
	  align-items: center;
	  justify-content: center;
	  border:1px solid #eee;
	  border-radius: calc((50px*0.7) / 2);
	  white-space: nowrap;
    }
    & > span.active{
      color: #ffffff;
      background-color: #409eff;
    }
  }
  .select {
    display: flex;
	justify-content: space-between;
    & > .firstColumn,.secondColumn {
	  flex-grow: 1;
      display: flex;
      justify-content: space-between;
      margin-bottom: 10px;
	  & > span {
		  margin-right: 10px;
	  }
      & > div {
        ::-webkit-input-placeholder {
          font-size: 13px;
        }
        ::-ms-input-placeholder {
          font-size: 13px;
        }
        ::input-placeholder {
          font-size: 13px;
        }
        display: flex;
        align-items: center;
        font-size: 15px;
        white-space: nowrap;
        &:last-of-type {
          padding-right: 15px;
        }
      }
    }
  }
}
.main-content {
  margin: 10px 15px;
  min-height: 530px;
  & > div:first-of-type {
    min-height: 400px;
  }
}
.el-pagination {
    padding: 40px 5px;
}
// 屏幕尺寸小于1500px以上运用以下样式
@media screen and (max-width: 1500px) {
	.main-head {
		.select {
			display: flex;
			flex-direction: column;
			.firstColumn,.secondColumn{
				display: flex;
				justify-content: flex-start;
			}
			.firstColumn {
				&>div:last-of-type{
					margin-left: 100px;
				}
			}
			.secondColumn {
				.billNum {
					width:190px!important;
				}
				.high-level{
					width:324px!important;
				}
				&>div:nth-child(2){
					margin-left: 100px;
				}
				&>div:last-of-type{
					margin-left: 100px;
				}								
			}
		}	
	}
	.main-content {
		min-height: 420px;
		& > div:first-of-type {
			min-height: 300px;
		}		
	}	
}
</style>